package com.google.gwt.livinglife.server;


import java.util.HashSet;
import java.util.Iterator;

import javax.jdo.PersistenceManager;

import com.google.gwt.livinglife.client.data.*;
import com.google.gwt.livinglife.server.data.*;

/**
 * This class is responsible for taking Persistent capable objects and translating 
 * them into corresponding GWT serializable objects.
 * NOTE: This class would not translate responses associated with a challenge or
 *       Comments associated with a Response from ID to corresponding Data object
 *       Since that can be an expensive operation hence we require the caller to fill in those
 *       separately.  
 * @author amitprakash
 *
 */
public class DataObjectConverter {
  public static BasicPostData getBasicPostData(BasicPost bp) {
  	BasicPostData bpd = new BasicPostData();
  	fillBasicPostData(bpd, bp);
  	return bpd;
  }
  
  public static BasicPostWithStatsData getBasicPostWithStatsData(BasicPostWithStats bps) {
  	BasicPostWithStatsData bpsd = new BasicPostWithStatsData();
  	fillBasicPostWithStatsData(bpsd, bps);
  	return bpsd;
  }
  
  public static ChallengeData getChallengeData(Challenge c) {
  	ChallengeData cd = new ChallengeData();
  	fillChallengeData(cd, c);
  	return cd;
  }
  
  public static CommentData getCommentData(Comment c) {
  	CommentData cd = new CommentData();
  	fillCommentData(cd, c);
  	return cd;
  }
  public static ResponseData getResponseData(Response r) {
  	ResponseData rd = new ResponseData();
  	fillResponseData(rd, r);
  	return rd;
  }
  public static LivingLifeUserData getLivingLifeUserData(LivingLifeUser u) {
  	LivingLifeUserData ud = new LivingLifeUserData();
  	ud.setCommunication_email(u.getCommunication_email());
  	Iterator<Long> iterator = u.getGroups().iterator();
  	while(iterator.hasNext()) {
  		PersistenceManager pm = PMF.get().getPersistenceManager();
  		try {
  			LivingLifeGroup g = pm.getObjectById(LivingLifeGroup.class, iterator.next());
  			GroupIdData gd = new GroupIdData(g.getId(), g.getName());
  			ud.getGroups().add(gd);
  		} catch (Exception e) {
  			// TODO: Due to some inconsistencies deleting groups, it is possible that a group_id may exist but
  			// but no object corresponding to it. Need to fix this.
  		} finally {
  			pm.close();
  		}
  	} 
  	ud.setId(u.getId());
  	ud.setNickname(u.getNickname());
  	if (u.getPicture_url() != null) {
  		ud.setPicture_url(u.getPicture_url().getValue());
  	}
  	return ud;
  }
  
  public static LivingLifeGroupData getlLivingLifeGroupData(LivingLifeGroup g) {
  	LivingLifeGroupData gd = new LivingLifeGroupData();
  	gd.setId(g.getId());
  	if (g.getDescription() != null) {
  		gd.setDescription(g.getDescription().getValue());
  	}
  	Iterator<String> member_iterator = g.getMembers().iterator();
  	while(member_iterator.hasNext()) {
  		PersistenceManager pm = PMF.get().getPersistenceManager();
  		try {
  			LivingLifeUser u = pm.getObjectById(LivingLifeUser.class, member_iterator.next());
  			UserIdData uid_data = new UserIdData(u.getNickname(), u.getId());
  			gd.getMembers().add(uid_data);
  		} finally {
  			pm.close();
  		}
  	}
  	Iterator<String> moderator_iterator = g.getMembers().iterator();
  	while(moderator_iterator.hasNext()) {
  		PersistenceManager pm = PMF.get().getPersistenceManager();
  		try {
  			LivingLifeUser u = pm.getObjectById(LivingLifeUser.class, moderator_iterator.next());
  			UserIdData uid_data = new UserIdData(u.getNickname(), u.getId());
  			gd.getModerators().add(uid_data);
  		} finally {
  			pm.close();
  		}
  	}  	
  	gd.setName(g.getName());
  	return gd;
  }

	public static UserIdData getUserIdData(LivingLifeUser user) {
		UserIdData uid = new UserIdData();
		uid.setId(user.getId());
		uid.setNickname(user.getNickname());
		return uid;
	}

	public static GroupIdData getGroupIdData(LivingLifeGroup group) {
		GroupIdData gid = new GroupIdData();
		gid.setGroup_name(group.getName());
		gid.setId(group.getId());
		return gid;
	}
  private static  void fillBasicPostData(BasicPostData bpd, BasicPost bp) {
  	UserIdData uid = new UserIdData();
  	uid.setId(bp.getAuthor_id());
  	uid.setNickname(bp.getAuthor());
  	bpd.setAuthor(uid);
  	bpd.setCreation_date(bp.getCreation_date());
  	if (bp.getEmbeded_image() != null) {
  	  bpd.setEmbeded_image(bp.getEmbeded_image().getValue());
  	}
  	if (bp.getPost_text() != null) {
  	  bpd.setPost_text(bp.getPost_text().getValue());
  	}
  	bpd.setId(bp.getId());
  }
  
  private static void fillBasicPostWithStatsData(BasicPostWithStatsData bpd, BasicPostWithStats bp) {
  	fillBasicPostData(bpd, bp);
  	bpd.setNum_inappropriate(bp.getNum_inappropriate());
  	bpd.setNum_inspired(bp.getNum_inspired());
  	bpd.setNum_liked(bp.getNum_liked());
  }
  
  private static void fillChallengeData(ChallengeData cd, Challenge c) {
  	fillBasicPostWithStatsData(cd, c);
    cd.setGroup_id(c.getGroup_id());
    cd.setNum_responses(c.getResponses().size());
    cd.setGroup_name(c.getGroup_name());
  }
  
  private static void fillResponseData(ResponseData rd, Response r) {
  	fillBasicPostWithStatsData(rd, r);
  	rd.setChallenge(r.getChallenge());
  	rd.setNum_comments(r.getComments().size());
  }
  
  private static void fillCommentData(CommentData cd, Comment c) {
  	fillBasicPostData(cd, c);
  	cd.setParent_response_id(c.getParent_response_id());
  }  
}
